require "rest-client"
require "json"
require "base64"

class RelevanceIssueAnalysis
  def initialize(repo, head_sha, pr_iid, access_token_str)

    @repo = repo
    @access_token = Base64.decode64(access_token_str)[0...32]
    @head_sha = head_sha
    @pr_iid = pr_iid
  end

  def exec
    create_check_run
    processing
  end

  def create_check_run
    data = {
      access_token: @access_token,
      details_url: "https://gitee.com/liwen",
      name: "关联 Issue 检测",
      head_sha: @head_sha
    }
    url = "https://gitee.com/api/v5/repos/#{@repo}/check-runs"
    @response_json = RestClient.post url, data
    @response = JSON.parse(@response_json)
    @check_run_id = @response["id"]
    puts "@check_run_id => #{@check_run_id}"
  end

  def processing
    url = "https://gitee.com/api/v5/repos/#{@repo}/check-runs/#{@check_run_id}"
    data = {
      access_token: @access_token,
      status: "in_progress"
    }
    RestClient.patch url, data
    analyse_and_finished_check
  end

  def analyse_and_finished_check
    puts "begining analyse repo"

    if analyse_issue_exist?
      conclusion = "success"
      summary = "🚀 Good job! 此 PR 已关联了 Issue" 
      text = ""
    else
      conclusion = "failure"
      summary = "💀 Oh, my God! 此 PR 竟然还未关联 Issue" 
      text = "注意：没有关联 Issue 的 PR 不能被合并；即时管理员临时合并了，也需要补充关联"
    end


    url = "https://gitee.com/api/v5/repos/#{@repo}/check-runs/#{@check_run_id}"
    data = {
      access_token: @access_token,
      conclusion: conclusion,
      output: {
        title: "Issue 关联检测",
        summary: summary,
        text: text,
        annotations: []
      }
    }
    puts "finished analyse, completed check run, data: \n #{data}"
    response = RestClient.patch url, data
    puts "response: #{response.body}"
    update_pr_label(conclusion)
  end

  def analyse_issue_exist?
    response = RestClient.get "https://gitee.com/api/v5/repos/#{@repo}/pulls/#{@pr_iid}/issues?access_token=#{@access_token}"
    issues = JSON.parse(response) rescue []
    !issues.empty?
  end

  def update_pr_label(conclusion)
    response = RestClient.get "https://gitee.com/api/v5/repos/#{@repo}/pulls/#{@pr_iid}/labels?access_token=#{@access_token}"
    labels = JSON.parse(response) rescue []
    label_names = labels.map {|label| label["name"]}
    if conclusion == "success"
      delete_pr_label("未关联Issue") if label_names.include?("未关联Issue")
      insert_pr_label("关联Issue") unless label_names.include?("关联Issue")
    else
      delete_pr_label("关联Issue") if label_names.include?("关联Issue")
      insert_pr_label("未关联Issue") unless label_names.include?("未关联Issue")
    end
  end

  def delete_pr_label(label_name)
    begin
      url = "https://gitee.com/api/v5/repos/#{@repo}/pulls/#{@pr_iid}/labels/#{label_name}?access_token=#{@access_token}"
      RestClient.delete URI.escape(url)
    rescue Exception => e
      puts "delete label: #{label_name} failure, e => #{e}"
    end
  end

  def insert_pr_label(label_name)
    begin
      url = "https://gitee.com/api/v5/repos/#{@repo}/pulls/#{@pr_iid}/labels?access_token=#{@access_token}"
      RestClient.post URI.escape(url), [label_name].to_json, {content_type: :json, accept: :json}
    rescue Exception => e
      puts "insert label: #{label_name} failure, e => #{e}"
    end
  end

end

inputted_strings = ARGV
if ARGV.empty?
  puts "nothing :("
else
  repo, head_sha, pr_iid, access_token_str = inputted_strings
  puts "repo: #{repo}, head_sha: #{head_sha}"
  RelevanceIssueAnalysis.new(repo, head_sha, pr_iid, access_token_str).exec
end
